<template>
  <div 
    class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
    v-if="visible"
    @click="handleOverlayClick"
  >
    <!-- 模态框容器 -->
    <div 
      class="bg-white rounded-lg shadow-xl w-full max-w-md mx-auto transform transition-all duration-300 scale-100"
      @click.stop
    >
      <!-- 模态框头部 -->
      <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
        <h3 class="text-lg font-medium text-gray-900">编辑角色</h3>
        <button 
          class="text-gray-400 hover:text-gray-500 focus:outline-none"
          @click="handleClose"
          aria-label="关闭"
        >
          <i class="fa fa-times"></i>
        </button>
      </div>
      
      <!-- 模态框内容 -->
      <div class="px-6 py-5">
        <form @submit.prevent="handleSubmit">
          <!-- 角色名称 -->
          <div class="mb-4">
            <label for="name" class="block text-sm font-medium text-gray-700 mb-1">
              角色名称 <span class="text-red-500">*</span>
            </label>
            <input
              id="name"
              v-model="formData.name"
              type="text"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors"
              :class="errors.name ? 'border-red-500 focus:ring-red-500 focus:border-red-500' : ''"
              :disabled="isSystemRole"
              placeholder="请输入角色名称"
            >
            <p v-if="errors.name" class="mt-1 text-sm text-red-600">{{ errors.name }}</p>
          </div>
          
          <!-- 角色编码 -->
          <div class="mb-4">
            <label for="code" class="block text-sm font-medium text-gray-700 mb-1">
              角色编码 <span class="text-red-500">*</span>
            </label>
            <input
              id="code"
              v-model="formData.code"
              type="text"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors font-mono text-sm"
              :class="errors.code ? 'border-red-500 focus:ring-red-500 focus:border-red-500' : ''"
              :disabled="isSystemRole"
              placeholder="请输入角色编码（英文/数字/下划线）"
            >
            <p v-if="errors.code" class="mt-1 text-sm text-red-600">{{ errors.code }}</p>
            <p class="mt-1 text-xs text-gray-500">
              用于系统内部标识，建议使用小写字母、数字和下划线
            </p>
          </div>
          
          <!-- 角色描述 -->
          <div class="mb-4">
            <label for="description" class="block text-sm font-medium text-gray-700 mb-1">
              角色描述
            </label>
            <textarea
              id="description"
              v-model="formData.description"
              rows="3"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors"
              placeholder="请输入角色描述信息"
            ></textarea>
          </div>
          
          <!-- 系统角色提示 -->
          <div v-if="isSystemRole" class="bg-yellow-50 border-l-4 border-yellow-400 p-3 rounded mb-2">
            <div class="flex">
              <div class="flex-shrink-0">
                <i class="fa fa-info-circle text-yellow-500"></i>
              </div>
              <div class="ml-3">
                <p class="text-sm text-yellow-700">
                  这是系统内置角色，角色名称和编码不可修改。
                </p>
              </div>
            </div>
          </div>
        </form>
      </div>
      
      <!-- 模态框底部 -->
      <div class="px-6 py-4 bg-gray-50 rounded-b-lg flex justify-end space-x-3">
        <button
          type="button"
          class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
          @click="handleClose"
          :disabled="loading"
        >
          取消
        </button>
        <button
          type="button"
          class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
          @click="handleSubmit"
          :disabled="loading || (isSystemRole && !canEditSystemRole)"
        >
          <i v-if="loading" class="fa fa-spinner fa-spin mr-1"></i>
          保存更改
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, watch, computed } from 'vue';
import { useValidator } from '@/composables/useValidator';

export default {
  props: {
    // 控制模态框显示/隐藏
    visible: {
      type: Boolean,
      default: false
    },
    // 角色数据
    role: {
      type: Object,
      default: () => ({
        id: null,
        name: '',
        code: '',
        description: '',
        isSystemRole: false
      })
    }
  },
  emits: ['close', 'save'],
  setup(props, { emit }) {
    // 表单数据
    const formData = ref({
      id: null,
      name: '',
      code: '',
      description: '',
      isSystemRole: false
    });
    
    // 错误信息
    const errors = ref({});
    
    // 加载状态
    const loading = ref(false);
    
    // 验证器 composable
    const { validateRequired, validateCode } = useValidator();
    
    // 系统角色判断
    const isSystemRole = computed(() => formData.value.isSystemRole);
    
    // 是否可以编辑系统角色（即使是系统角色，描述也可以编辑）
    const canEditSystemRole = computed(() => {
      return formData.value.description !== props.role.description;
    });
    
    // 监听角色数据变化，同步到表单
    watch(() => props.role, (newRole) => {
      if (newRole) {
        formData.value = { ...newRole };
        // 重置错误
        errors.value = {};
      }
    }, { immediate: true, deep: true });
    
    // 监听visible变化，重置状态
    watch(() => props.visible, (isVisible) => {
      if (!isVisible) {
        loading.value = false;
      }
    });
    
    // 表单验证
    const validateForm = () => {
      const newErrors = {};
      
      // 验证角色名称
      if (!validateRequired(formData.value.name)) {
        newErrors.name = '请输入角色名称';
      } else if (formData.value.name.length < 2 || formData.value.name.length > 50) {
        newErrors.name = '角色名称长度必须在2-50个字符之间';
      }
      
      // 验证角色编码
      if (!validateRequired(formData.value.code)) {
        newErrors.code = '请输入角色编码';
      } else if (!validateCode(formData.value.code)) {
        newErrors.code = '角色编码只能包含字母、数字和下划线';
      } else if (formData.value.code.length < 2 || formData.value.code.length > 30) {
        newErrors.code = '角色编码长度必须在2-30个字符之间';
      }
      
      // 更新错误信息
      errors.value = newErrors;
      
      // 返回是否验证通过
      return Object.keys(newErrors).length === 0;
    };
    
    // 处理提交
    const handleSubmit = async () => {
      // 表单验证
      if (!validateForm()) {
        // 自动聚焦到第一个错误字段
        const firstErrorField = Object.keys(errors.value)[0];
        document.getElementById(firstErrorField)?.focus();
        return;
      }
      
      try {
        loading.value = true;
        // 触发保存事件，将表单数据传递给父组件
        emit('save', { ...formData.value });
      } catch (error) {
        console.error('提交表单失败:', error);
      } finally {
        loading.value = false;
      }
    };
    
    // 处理关闭
    const handleClose = () => {
      emit('close');
    };
    
    // 点击遮罩层关闭
    const handleOverlayClick = () => {
      handleClose();
    };
    
    return {
      formData,
      errors,
      loading,
      isSystemRole,
      canEditSystemRole,
      handleSubmit,
      handleClose,
      handleOverlayClick
    };
  }
};
</script>

<style scoped>
/* 动画效果 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scaleIn {
  from { transform: scale(0.95); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.fixed.inset-0 {
  animation: fadeIn 0.2s ease-out forwards;
}

.bg-white.rounded-lg {
  animation: scaleIn 0.2s ease-out forwards;
}

/* 禁用状态样式 */
input:disabled, textarea:disabled {
  background-color: #f9fafb;
  cursor: not-allowed;
  opacity: 0.7;
}
</style>
    